package com.threeox.commonlibrary.util.engine;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;

import com.threeox.commonlibrary.R;
import com.threeox.commonlibrary.annotation.ListModelExtend;
import com.threeox.commonlibrary.annotation.ModelExtend;
import com.threeox.commonlibrary.annotation.MultiPageExtend;
import com.threeox.commonlibrary.annotation.TableModelExtend;
import com.threeox.utillibrary.util.EmptyUtils;
import com.threeox.utillibrary.util.LogUtils;
import com.threeox.utillibrary.util.java.JAVAUtil;
import com.threeox.utillibrary.util.res.IdHelper;
import com.threeox.utillibrary.util.res.RawHelper;
import com.threeox.utillibrary.util.res.StringHelper;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @ClassName: AnnotationUtil
 *
 * @Description: TODO(注解信息解析的工具类)
 *
 * @author 赵屈犇
 *
 * @date 创建时间: 2017/7/7 14:22
 *
 * @version 1.0
 *
 */
public class AnnotationUtil {

    private final String TAG = this.getClass().getName();

    private static AnnotationUtil mInstance = null;

    private Context mContext = null;
    private IdHelper idHelper = null;
    private JAVAUtil mJAVAUtil = null;

    private List<String> ALLEXTENDPACKS = new ArrayList<String>();
    private String[] MODELEXTENDPACKS, LISTMODELEXTENDPACKS, MULTIPAGEEXTENDPACKS, TABLEMODELEXTENDPACKS;

    private List<Class> mAllClass;// 缓存所有的能用到的Class

    private Map<Object, String> mModelExtends = new HashMap<Object, String>();

    private Map<Object, String> mListModelExtends = new HashMap<Object, String>();

    private Map<Object, String> mMultiPageExtends = new HashMap<Object, String>();

    private Map<Object, String> mTableModelExtends = new HashMap<Object, String>();

    private AnnotationUtil() {
        throw new UnsupportedOperationException("不能初始化AnnotationUtil");
    }

    private AnnotationUtil(Context context) {
        try {
            this.mContext = context;
            this.mJAVAUtil = JAVAUtil.getInstance(context);
            this.idHelper = IdHelper.newInstance(context);
            ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
            Bundle metaData = appInfo.metaData;
            StringHelper stringHelper = StringHelper.newInstance(context);
            if (metaData != null) {
                String modelextendPacks = stringHelper.getString(R.string.modelextend_packs);
                if (metaData.containsKey(modelextendPacks)) {
                    String packNames = metaData.getString(modelextendPacks);
                    if (EmptyUtils.isNotEmpty(packNames)) {
                        this.MODELEXTENDPACKS = packNames.split("\\|");
                        this.ALLEXTENDPACKS.addAll(Arrays.asList(MODELEXTENDPACKS));
                    }
                }
                String listModelExtendPacks = stringHelper.getString(R.string.listmodelextend_packs);
                if (metaData.containsKey(listModelExtendPacks)) {
                    String packNames = metaData.getString(listModelExtendPacks);
                    if (EmptyUtils.isNotEmpty(packNames)) {
                        this.LISTMODELEXTENDPACKS = packNames.split("\\|");
                        this.ALLEXTENDPACKS.addAll(Arrays.asList(LISTMODELEXTENDPACKS));
                    }
                }
                String multiPageExtendPacks = stringHelper.getString(R.string.multipageextend_packs);
                if (metaData.containsKey(multiPageExtendPacks)) {
                    String packNames = metaData.getString(multiPageExtendPacks);
                    if (EmptyUtils.isNotEmpty(packNames)) {
                        this.MULTIPAGEEXTENDPACKS = packNames.split("\\|");
                        this.ALLEXTENDPACKS.addAll(Arrays.asList(MULTIPAGEEXTENDPACKS));
                    }
                }
                String tableModelExtendPacks = stringHelper.getString(R.string.tablemodelextend_packs);
                if (metaData.containsKey(tableModelExtendPacks)) {
                    String packNames = metaData.getString(tableModelExtendPacks);
                    if (EmptyUtils.isNotEmpty(packNames)) {
                        this.TABLEMODELEXTENDPACKS = packNames.split("\\|");
                        this.ALLEXTENDPACKS.addAll(Arrays.asList(TABLEMODELEXTENDPACKS));
                    }
                }
            }
        } catch (Exception e) {
            LogUtils.e(TAG, "初始化:" + e.getMessage());
        }
    }

    public static AnnotationUtil getInstance(Context context) {
        if (mInstance == null) {
            synchronized (AnnotationUtil.class) {
                if (mInstance == null) {
                    mInstance = new AnnotationUtil(context);
                }
            }
        }
        return mInstance;
    }

    /**
     * 初始化所有的类
     */
    public synchronized void initAllClass() {
        if (EmptyUtils.isEmpty(mAllClass)) {
            Long startTime = System.currentTimeMillis();
            List<Class<? extends Annotation>> annotations = new ArrayList<Class<? extends Annotation>>();
            annotations.add(ModelExtend.class);
            annotations.add(ListModelExtend.class);
            annotations.add(MultiPageExtend.class);
            annotations.add(TableModelExtend.class);
            String[] extendPacks = new String[ALLEXTENDPACKS.size()];
            ALLEXTENDPACKS.toArray(extendPacks);
            mAllClass = mJAVAUtil.getClazzByPackage(annotations, extendPacks);
            initModelExtendClass();
            initListModelExtendClass();
            initMultiPageExtendClass();
            initTableModelExtendClass();
            LogUtils.d(TAG, "初始化完成所有类;用时:" + (System.currentTimeMillis() - startTime));
        }
    }

    /**
     * 根据Key值得到模型驱动的扩展类
     *
     * @param key
     * @return
     */
    public String getModelExtendClass(Object key) {
        initModelExtendClass();
        return mModelExtends.get(key);
    }

    /**
     * 初始化所有页面模型扩展类
     */
    private void initModelExtendClass() {
        try {
            if (EmptyUtils.isEmpty(mModelExtends)) {
                for (Class packClazz : mAllClass) {
                    ModelExtend modelExtend = (ModelExtend) packClazz.getAnnotation(ModelExtend.class);
                    if (modelExtend != null) {
                        int[] values = modelExtend.value();
                        if (EmptyUtils.isNotEmpty(values)) {
                            for (int i = 0; i < values.length; i++) {
                                mModelExtends.put(values[i], packClazz.getName());
                            }
                        }
                        String[] fileNames = modelExtend.fileName();
                        if (EmptyUtils.isNotEmpty(fileNames)) {
                            for (int i = 0; i < fileNames.length; i++) {
                                mModelExtends.put(changeFileId(fileNames[i]), packClazz.getName());
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            LogUtils.e(TAG, "getModelExtendClass:报错了:" + e.getMessage());
        }
    }

    /**
     * 根据Key值得到列表模型驱动的扩展类
     *
     * @param key
     * @return
     */
    public String getListModelExtendClass(Object key) {
        initListModelExtendClass();
        return mListModelExtends.get(key);
    }

    /**
     * 初始化所有列表模型扩炸雷
     */
    private void initListModelExtendClass() {
        try {
            if (EmptyUtils.isEmpty(mListModelExtends)) {
                for (Class packClazz : mAllClass) {
                    ListModelExtend modelExtend = (ListModelExtend) packClazz.getAnnotation(ListModelExtend.class);
                    if (modelExtend != null) {
                        int[] values = modelExtend.value();
                        if (EmptyUtils.isNotEmpty(values)) {
                            for (int i = 0; i < values.length; i++) {
                                mListModelExtends.put(values[i], packClazz.getName());
                            }
                        }
                        String[] fileNames = modelExtend.fileName();
                        if (EmptyUtils.isNotEmpty(fileNames)) {
                            for (int i = 0; i < fileNames.length; i++) {
                                mListModelExtends.put(changeFileId(fileNames[i]), packClazz.getName());
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            LogUtils.e(TAG, "getListModelExtendClass:报错了:" + e.getMessage());
        }
    }

    /**
     * 根据Key值得到多页面模型驱动的扩展类
     *
     * @param key
     * @return
     */
    public String getMultiPageExtendClass(Object key) {
        initMultiPageExtendClass();
        return mMultiPageExtends.get(key);
    }

    /**
     * 初始化所有多页面模型驱动扩展类
     */
    private void initMultiPageExtendClass() {
        try {
            if (EmptyUtils.isEmpty(mMultiPageExtends)) {
                for (Class packClazz : mAllClass) {
                    MultiPageExtend multiPageExtend = (MultiPageExtend) packClazz.getAnnotation(MultiPageExtend.class);
                    if (multiPageExtend != null) {
                        int[] values = multiPageExtend.value();
                        if (EmptyUtils.isNotEmpty(values)) {
                            for (int i = 0; i < values.length; i++) {
                                mMultiPageExtends.put(values[i], packClazz.getName());
                            }
                        }
                        String[] fileNames = multiPageExtend.fileName();
                        if (EmptyUtils.isNotEmpty(fileNames)) {
                            for (int i = 0; i < fileNames.length; i++) {
                                mMultiPageExtends.put(changeFileId(fileNames[i]), packClazz.getName());
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            LogUtils.e(TAG, "getMultiPageExtendClass:报错了:" + e.getMessage());
        }
    }

    /**
     * 得到表模型扩展类
     *
     * @param key
     * @return
     */
    public String getTableModelExtendClass(Object key) {
        initTableModelExtendClass();
        return mTableModelExtends.get(key);
    }

    /**
     * 初始化所有表格模型扩展类
     */
    private void initTableModelExtendClass() {
        try {
            if (EmptyUtils.isEmpty(mTableModelExtends)) {
                for (Class packClazz : mAllClass) {
                    TableModelExtend tableModelExtend = (TableModelExtend) packClazz.getAnnotation(TableModelExtend.class);
                    if (tableModelExtend != null) {
                        int[] values = tableModelExtend.value();
                        if (EmptyUtils.isNotEmpty(values)) {
                            for (int i = 0; i < values.length; i++) {
                                mTableModelExtends.put(values[i], packClazz.getName());
                            }
                        }
                        String[] fileNames = tableModelExtend.fileName();
                        if (EmptyUtils.isNotEmpty(fileNames)) {
                            for (int i = 0; i < fileNames.length; i++) {
                                mTableModelExtends.put(changeFileId(fileNames[i]), packClazz.getName());
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            LogUtils.e(TAG, "getTableModelExtendClass:报错了:" + e.getMessage());
        }
    }


    /**
     * 转换文件ID
     * @param fileName
     * @return
     */
    private Object changeFileId(String fileName) {
        // 转换一下文件ID
        Integer fileId = idHelper.getIdByName(fileName, IdHelper.ResType.raw);
        return ((fileId == null) ? fileName : fileId);
    }

}
